from time import sleep, strftime, strptime, time, mktime
import pickle
from datetime import date, timedelta
from os import listdir, remove
from os.path import join, exists
from re import search
from kdriver import Kdriver
from info import Info


class Action(Kdriver):
    def __init__(self):
        super(Action, self).__init__()
        self.remove_temp_img()
        self.login_url = 'https://passport.jd.com/new/login.aspx'
        self.home_url = 'https://www.jd.com/'
        self.shopcar_url = 'https://cart.jd.com/cart_index/'

    def main(self):
        self.get_input_data()
        # 登录
        if not self.login_if_cookie_effective():
            self.guide_manual_login() if int(Info.is_manual) else self.auto_login()
        #等待预定时间到达
        self.wait_time_up()
        #根据链接加入购物车
        for goods in Info.goods:
            self.add_with_url(goods['goods_url'], goods['goods_num'])
        # 进入购物车
        self.driver.get(self.shopcar_url)
        #提交购物车全部商品订单
        self.buy_all_in_shoppingcar()

    def get_input_data(self):
        self.driver.get('file:///' + Info.ui_path)
        if self.wait_element_load('.trigger_run', 24*60*60):
            data_list = self.driver.find_elements_by_css_selector('.data_dict > li')
            goods_list = self.driver.find_elements_by_class_name('data_dict_goods')
            for data_block in data_list:
                key = data_block.get_attribute('class')
                value = data_block.get_attribute('textContent')
                setattr(Info, key, value)
            for goods_block in goods_list:
                goods_data = goods_block.find_elements_by_tag_name('li')
                temp = {}
                for goods_param in goods_data:
                    key = goods_param.get_attribute('class')
                    value = goods_param.get_attribute('textContent')
                    temp[key] = value
                Info.goods.append(temp)

    def guide_manual_login(self):
        self.driver.get(self.login_url)
        sleep(30)
        if self.is_login():
            self.save_cookie()
        else:
            raise TimeoutError

    def add_with_url(self, target_url, goods_num):
        self.driver.get(target_url)
        self.driver.find_element_by_id('buy-num').clear()
        self.driver.find_element_by_id('buy-num').send_keys(goods_num)
        self.wait_element_load('#InitCartUrl', 120)
        sleep(2)
        self.driver.find_element_by_id('InitCartUrl').click()

    def buy_all_in_shoppingcar(self):
        #购物车全选
        secect_all_checkbox = self.driver.find_element_by_css_selector('.select-all > .jdcheckbox')
        secect_state = secect_all_checkbox.get_attribute('clstag').split('|')[-1]
        if not int(secect_state):
            secect_all_checkbox.click()
        #点击支付
        self.driver.find_element_by_class_name('common-submit-btn').click()
        #提交订单
        self.wait_element_load('#sumPayPriceId')
        # cost_raw = self.driver.find_element_by_id('sumPayPriceId').text
        # cost_really = sub('[^./0-9]', '', cost_raw)
        # if isinstance(Info.cost_limit, int) or isinstance(Info.cost_limit, str):
        #     if not cost_really == int(Info.cost_limit):
        #         raise ValueError('实际付款值与预期值不同，支付被阻止')
        # elif isinstance(Info.cost_limit, list):
        #     if not (cost_really>Info.cost_limit[0] and cost_really<Info.cost_limit[1]):
        #         raise ValueError('实际付款值与预期值不同，支付被阻止')
        # else:
        #     raise ValueError('Info.cost_limit数值不符合要求')
        self.driver.find_element_by_id('order-submit').click()

    def remove_temp_img(self):
        files = listdir(Info.temp_img_path)
        for file in files:
            if 'png' in file or 'jpg' in file:
                remove(join(Info.temp_img_path, file))

    def wait_time_up(self):
        run_time = search('(\d{2}:\d{2}:\d{2})', Info.run_time).group(0)
        now_datetime = strftime('%Y-%m-%d %H:%M:%S').split(' ')
        if Info.run_date == 'today':
            run_date = now_datetime[0]
        # elif Info.run_date == 'tomorrow':
        else:
            run_date = (date.today() + timedelta(days=1)).strftime("%Y-%m-%d")
        if run_time == 'now':
            run_time = now_datetime[1]
        time_raw = run_date + ' ' + run_time
        time_array = strptime(time_raw, "%Y-%m-%d %H:%M:%S")
        self.limit_time = int(mktime(time_array))
        while time() < self.limit_time:
            sleep(0.5)

    def delete_all_in_shoppingcar(self):
        pass

    def login_if_cookie_effective(self):
        if not exists(Info.cookie_path):
            return False
        driver = self.driver
        driver.get(self.home_url)
        self.load_cookie(Info.cookie_path)
        self.driver.get(self.home_url)
        return self.is_login()

    def is_login(self):
        if self.driver.current_url == self.home_url \
                and not self.is_exist('.link-login', text='你好，请登录'):
            return True
        return False

    def auto_login(self):
        driver = self.driver
        driver.get(self.login_url)
        driver.maximize_window()
        #输入用户名密码
        driver.find_element_by_css_selector('.login-tab-r').click()
        driver.find_element_by_css_selector('#loginname').send_keys(Info.jd_conut)
        driver.find_element_by_css_selector('#nloginpwd').send_keys(Info.jd_password + '\n')
        #加载验证图片
        self.wait_element_load('.JDJRV-bigimg > img')
        if not self.move_slider():
            raise Exception
        self.save_cookie()

    def save_cookie(self):
        cookies = self.driver.get_cookies()
        with open(Info.cookie_path, 'wb+') as fh:
            pickle.dump(cookies, fh)

    def move_slider(self):
        from kvalidate import Kvalidate
        k = Kvalidate(self.driver)
        index = 0
        while not self.is_login():
            index += 1
            if index > 20:
                return False
            sleep(1)
            bg_b64data = self.driver.find_element_by_css_selector('.JDJRV-bigimg > img').get_attribute('src')
            gap_b64data = self.driver.find_element_by_css_selector('.JDJRV-smallimg > img').get_attribute('src')
            bg = k.save_base64_to_png(bg_b64data)
            gap = k.save_base64_to_png(gap_b64data)
            move_length = k.get_move_length(bg, gap)
            tracks = k.get_tracks(move_length)
            slider = self.driver.find_element_by_class_name('JDJRV-slide-btn')
            k.slider_action(tracks, slider)
            sleep(1)
        return True


if __name__ == '__main__':
    try:
        action = Action()
        action.main()
    except:
        import traceback
        print(traceback.print_exc())
